package com.atguigu.stgy.admin.service.impl;

import com.atguigu.stgy.admin.service.*;
import com.atguigu.stgy.model.dto.ApartmentDTO;
import com.atguigu.stgy.model.dto.ApartmentSearchDTO;
import com.atguigu.stgy.model.entity.*;
import com.atguigu.stgy.model.vo.ApartmentDetailVO;
import com.atguigu.stgy.model.vo.ApartmentVO;
import com.atguigu.stgy.model.vo.FeeValueVO;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.atguigu.stgy.admin.mapper.ApartmentInfoMapper;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class ApartmentInfoServiceImpl extends ServiceImpl<ApartmentInfoMapper, ApartmentInfo> implements ApartmentInfoService {
    @Resource
    ProvinceInfoService provinceInfoService;
    @Resource
    CityInfoService cityInfoService;
    @Resource
    DistrictInfoService districtInfoService;
    @Resource
    ApartmentFacilityService apartmentFacilityService;
    @Resource
    ApartmentLabelService apartmentLabelService;
    @Resource
    ApartmentFeeValueService apartmentFeeValueService;

    @Resource
    GraphInfoService graphInfoService;
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveOrUpdateApartmentDTO(ApartmentDTO apartmentDTO) {
        //新增:apartmentDTO存在id值 表示更新
        if(apartmentDTO.getId() ==null ){
            //新增
            saveApartmentDTO(apartmentDTO);
            return;
        }
        //更新
        updateApartmentDTO(apartmentDTO);

    }
    @Transactional(rollbackFor = Exception.class)
    public void updateApartmentDTO(ApartmentDTO apartmentDTO) {
        //1、更新公寓信息Apartmentinfo表
        ApartmentInfo apartmentInfo = new ApartmentInfo();
        BeanUtils.copyProperties(apartmentDTO , apartmentInfo);
        this.updateById(apartmentInfo);
        //下面是公寓一对多的属性列表，前端可能改了一个或多个或0个
        //一般先删除所有  然后保存本次提交的
        //2、更新公寓图片信息
        graphInfoService.updateApartmentGraphInfos(apartmentDTO);
        //3、更新公寓的标签列表
        apartmentLabelService.updateApartmentLabelInfos(apartmentDTO);
        //4、更新公寓的配套列表
        apartmentFacilityService.updateApartmentFacilityInfos(apartmentDTO);

        //5、更新公寓的杂费列表
        apartmentFeeValueService.updateApartmentFeeValues(apartmentDTO);
    }

    private void saveApartmentDTO(ApartmentDTO apartmentDTO) {
        //拆分数据 完善数据 保存到对应的表中
        //1、保存公寓信息
        ApartmentInfo apartmentInfo = new ApartmentInfo();
        //将数据源相同名称类型的 属性设置给目标对象
        BeanUtils.copyProperties(apartmentDTO ,apartmentInfo);
        //is_release 属性 实体类去掉了is_前缀  导致属性值拷贝失败 需要手动设置
        apartmentInfo.setIsRelease(apartmentDTO.getIsRelease());
        //获取省市区名称
        ProvinceInfo provinceInfo = provinceInfoService.getById(apartmentInfo.getProvinceId());
        CityInfo cityInfo = cityInfoService.getById(apartmentInfo.getCityId());
        DistrictInfo districtInfo = districtInfoService.getById(apartmentInfo.getDistrictId());
        //设置省市区名称
        apartmentInfo.setProvinceName(provinceInfo.getName());
        apartmentInfo.setCityName(cityInfo.getName());
        apartmentInfo.setDistrictName(districtInfo.getName());
        //保存到数据库： id是代码通过雪花算法保存数据之前生成设置给该对象的
        this.save(apartmentInfo);
        //获取保存成功的公寓id
        Long apartmentInfoId = apartmentInfo.getId();
        //2、apartment_facility  保存公寓配套信息映射   一个公寓有多个配套信息  一个配套信息可以被多个公寓拥有  多对多映射
        apartmentFacilityService.batchSaveFacility(apartmentDTO, apartmentInfoId);

        //3、保存apartment_label  公寓标签信息
        apartmentLabelService.batchSaveLabel(apartmentDTO, apartmentInfoId);
        //4、保存apartment_fee_value  公寓杂费信息
        apartmentFeeValueService.batchSaveFeeValue(apartmentDTO, apartmentInfoId);

        //5、保存 公寓图片信息   公寓图片1：多
        graphInfoService.batchSaveGraphInfo(apartmentDTO, apartmentInfoId);

    }

    @Override
    public Page<ApartmentVO> pageItem(ApartmentSearchDTO searchDTO) {
        //根据条件查询 数据
        //apartment_info+room_info+lease_agreement
        Page<ApartmentVO> page = new Page<>(searchDTO.getCurrent() , searchDTO.getSize());
        // mp 自定义mapper方法 如果配置了分页拦截器，并且传入了page对象，mp会自动实现分页查询
        //调用自定义的mapper方法查询数据集合
        List<ApartmentVO> list = baseMapper.selectApartmentVOByCondition(page,searchDTO);
        page.setRecords(list);
        return page;
    }
    @Override
    public ApartmentDetailVO getDetailById(Long id) {
        //id查询公寓详情
        ApartmentInfo apartmentInfo = this.getById(id);
        //公寓id查询图片列表
        List<GraphInfo> graphInfos = graphInfoService.list(Wrappers.lambdaQuery(GraphInfo.class)
                .eq(GraphInfo::getItemId, id));
        //公寓id查询标签列表:  在中间表 apartment_label 中查询公寓的标签id列表  然后到标签表中查询标签列表
        List<LabelInfo> labelInfoList = apartmentLabelService.getLabelInfosByApartmentId(id);

        //公寓id查询配套列表:apartment_facility     facility_info
        List<FacilityInfo> facilityInfoList = apartmentFacilityService.getFacilityInfoByApartmentId(id);
        //公寓id查询杂费列表
        List<FeeValueVO> feeValueVoList = apartmentFeeValueService.getFeeValueVOsByApartmentId(id);

        //组装数据为ApartmentDetailVO对象
        ApartmentDetailVO apartmentDetailVO = new ApartmentDetailVO();
        BeanUtils.copyProperties(apartmentInfo , apartmentDetailVO);
        apartmentDetailVO.setGraphVoList(graphInfos);
        apartmentDetailVO.setLabelInfoList(labelInfoList);
        apartmentDetailVO.setFacilityInfoList(facilityInfoList);
        apartmentDetailVO.setFeeValueVoList(feeValueVoList);
        return apartmentDetailVO;
    }


}
